package com.cdu.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cdu.enums.MessageEnum;
import com.cdu.mapper.UserMapper;
import com.cdu.model.UserDetail;
import com.cdu.model.common.BaseResponse;
import com.cdu.model.common.PageResult;
import com.cdu.model.common.StringConst;
import com.cdu.model.query.UserQuery;
import com.cdu.pojo.News;
import com.cdu.pojo.Task;
import com.cdu.pojo.User;
import com.cdu.service.NewsService;
import com.cdu.service.TaskService;
import com.cdu.service.UserService;
import com.cdu.util.ConvertUtils;
import com.cdu.util.JWTUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Base64Utils;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;

/**
 * @program: easy-help-v2
 * @description:
 * @author: hanabi
 * @create: 2022-05-17 10:14
 **/
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final UserMapper userMapper;


    private final TaskService taskService;

    private final NewsService newsService;


    @Override
    public BaseResponse login(JSONObject ido) {
        JSONObject data = new JSONObject();
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>();
        wrapper.eq(User::getUsername, ido.getString("username"))
                .eq(User::getPassword, ido.getString("password"));
        User user = userMapper.selectOne(wrapper);
        if (null == user) {
            return BaseResponse.response(MessageEnum.INVALID_USERNAME_OR_PASSWORD);
        }
        String token = JWTUtil.createToken(user);
        data.put("token", Base64Utils.encodeToUrlSafeString(token.getBytes(StandardCharsets.UTF_8)));
        return BaseResponse.response(data, MessageEnum.SUCCESS);
    }

    @Override
    public BaseResponse register(JSONObject ido) {
        User user = new User();
        String username = ido.getString("username").trim();
        String password = ido.getString("password");
        if (!(StringUtils.hasLength(username) && StringUtils.hasLength(password))) {
            return BaseResponse.response(MessageEnum.INVALID_USERNAME_OR_PASSWORD);
        }
        if (userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username)) != null) {
            return BaseResponse.response(MessageEnum.USERNAME_EXIST);
        }
        user.setUsername(username);
        user.setPassword(password);
        user.setCreateTime(new Date());
        user.setRole(StringConst.ROLE_USER);
        userMapper.insert(user);
        return BaseResponse.response(MessageEnum.REGISTER_SUCCESS);
    }

    @Override
    public BaseResponse findUserDetailById(String id) {
        JSONObject data = new JSONObject();
        User user = userMapper.selectById(id);
        if (null == user) {
            return BaseResponse.response(null, MessageEnum.USER_NOT_EXIST);
        }
        var taskWrapper = new LambdaQueryWrapper<Task>();
        var newsWrapper = new LambdaQueryWrapper<News>();
        taskWrapper.eq(Task::getCreator, user.getId());
        newsWrapper.eq(News::getCreator, user.getId());
        List<Task> taskList = taskService.list(taskWrapper);
        List<News> newsList = newsService.list(newsWrapper);
        UserDetail userDetail = ConvertUtils.convertUserDetail(user, taskList, newsList);
        data.put("userDetail", JSON.toJSONString(userDetail));
        return BaseResponse.response(data, MessageEnum.SUCCESS);
    }

    @Override
    public BaseResponse queryUser(UserQuery userQuery) {
        // pageHelper:
        PageHelper.startPage(userQuery.getPageNum(), userQuery.getPageSize());
        // #################
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        // queryWrapper.eq(User::getId, userQuery.getId());
        queryWrapper.like(com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotEmpty(userQuery.getUsername()),User::getUsername, userQuery.getUsername());
        queryWrapper.like(com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotEmpty(userQuery.getRealName()),User::getRealName, userQuery.getRealName());
        List<User> users = userMapper.selectList(queryWrapper);

        var pageInfo = PageInfo.of(users);
        return BaseResponse.response(PageResult.doPage(pageInfo.getList(),
                pageInfo.getPageNum(),
                pageInfo.getPageSize(),
                pageInfo.getTotal()), MessageEnum.SUCCESS);
    }
}
